from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, PasswordField, BooleanField, SubmitField
from wtforms import validators
from wtforms.validators import DataRequired, ValidationError, Email, EqualTo, Length
from app.models import User


class LoginForm(FlaskForm):
    # 每个字段类都接受一个描述或别名作为第一个参数
    # 可选参数validators用于验证输入字段是否符合预期
    # DataRequired验证器仅验证字段输入是否为空
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('Remeber Me')
    submit = SubmitField('Sign In')


class RegistrationForm(FlaskForm):
    username = StringField('username', validators=[DataRequired()])
    # 在DataRequired之后添加了第二个验证器，名为Email
    # 确保用户在此字段中键入的内容与电子邮件地址的结构相匹配
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField(
        'Password', validators=[DataRequired()]
    )
    # 第二个password字段使用另一个名为EqualTo的验证器，
    # 它将确保其值与第一个password字段的值相同
    password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('password')]
    )
    submit = SubmitField('Register')


    # 当添加任何匹配模式validate_ <field_name>的方法时，
    # WTForms将这些方法作为自定义验证器，并在已设置验证器之后调用它们

    # 确保用户输入的username和email不会与数据库中已存在的数据冲突，所以这两个方法执行数据库查询，并期望结果集为空。 否则，则通过ValidationError触发验证错误。 
    # 异常中作为参数的消息将会在对应字段旁边显示，以供用户查看
    def validate_username(self, username):
        user = User.query.filter_by(username=username.data).first()
        if user is not None:
            raise ValidationError('Please use a differnet username.')
        
    def validate_email(self, email):
        user = User.query.filter_by(email=email.data).first()
        if user is not None:
            raise ValidationError('Please use a different email address.')



class EditProfileForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    # 一个新的字段类型和一个新的验证器: “about_me”字段, TextAreaField多行输入文本框
    # 为了验证这个字段的长度，我使用了Length
    about_me = TextAreaField('about me', validators=[Length(min=0, max=140)])
    submit = SubmitField('Submit')

    def __init__(self, original_username, *args, **kwargs):
        super(EditProfileForm, self).__init__(*args, **kwargs)
        self.original_username = original_username

    def validate_username(self, username):
        if username.data != self.original_username:
            user = User.query.filter_by(username=self.username.data).first()
            if user is not None:
                raise ValidationError('Please use a different username.')


class PostForm(FlaskForm):
    post = TextAreaField('Say something', validators=[
        DataRequired(), Length(min=1, max=140)])
    submit = SubmitField('Submit')


class ResetPasswordRequestForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email()])
    submit = SubmitField('Request Password Reset')


class ResetPasswordForm(FlaskForm):
    password = PasswordField('Password', validators=[DataRequired()])
    password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Request Password Reset')
